#include <stdlib.h>
#include <typeinfo>
#include <string>
#include "Arbre.h"
#include "Symbole.h"
#include "SymboleValue.h"

////////////////////////////////////////////////////////////////////////////////
// NoeudSeqInst
////////////////////////////////////////////////////////////////////////////////

NoeudSeqInst::NoeudSeqInst() : tabInst() {
}

////////////////////////////////////////////////////////////////////////////////

Valeur* NoeudSeqInst::getValeur() {
    for (unsigned int i = 0; i < tabInst.size(); i++) {
        tabInst[i]->getValeur();
    }
    return NULL; // par convention, resultat = valeur de la derniere instruction
}

////////////////////////////////////////////////////////////////////////////////

void NoeudSeqInst::afficher(unsigned short indentation) {
    Noeud::afficher(indentation);
    cout << "Noeud - Sequence de " << tabInst.size() << " instruction(s)" << endl;

    for (unsigned int i = 0; i < tabInst.size(); i++)
        tabInst[i]->afficher(indentation + 1); // on affiche les fils en augmentant l'indentation
}

////////////////////////////////////////////////////////////////////////////////

void NoeudSeqInst::afficherEnC(unsigned short indentation) {
    for (unsigned int i = 0; i < tabInst.size(); i++) {

        Noeud::afficher(indentation);
        tabInst[i]->afficherEnC(indentation); // on affiche les fils en augmentant l'indentation
        cout << ";" << endl;
    }
}

////////////////////////////////////////////////////////////////////////////////

void NoeudSeqInst::ajouteInstruction(Noeud* instruction) {

    tabInst.push_back(instruction);
}

////////////////////////////////////////////////////////////////////////////////
// NoeudAffectation
////////////////////////////////////////////////////////////////////////////////

NoeudAffectation::NoeudAffectation(Noeud* variable, Noeud* expression) {

    this->variable = variable;
    this->expression = expression;
}

////////////////////////////////////////////////////////////////////////////////

Valeur* NoeudAffectation::getValeur() {
    Valeur* valeur = NULL;
    if (typeid (*expression) == typeid (SymboleValue) &&
            *(SymboleValue*) expression == "<CHAINE>") {
        valeur = new ValeurChaine(((ValeurChaine*) expression->getValeur())->getValeur());
        ((SymboleValue*) variable)->setValeur(valeur);
    } else if (typeid (*expression) == typeid (SymboleValue) &&
            *(SymboleValue*) expression == "<CARACTERE>") {
        valeur = new ValeurCaractere(((ValeurCaractere*) expression->getValeur())->getValeur());
        ((SymboleValue*) variable)->setValeur(valeur);
    } else if (typeid (*expression) == typeid (SymboleValue) &&
            *(SymboleValue*) expression == "<ENTIER>") {
        valeur = new ValeurEntiere(((ValeurEntiere*) expression->getValeur())->getValeur());
        ((SymboleValue*) variable)->setValeur(valeur);
    } else if (typeid (*expression) == typeid (SymboleValue) &&
            *(SymboleValue*) expression == "<REEL>") {
        valeur = new ValeurReelle(((ValeurReelle*) expression->getValeur())->getValeur());
        ((SymboleValue*) variable)->setValeur(valeur);
    } else {
        ((SymboleValue*) variable)->setValeur(expression->getValeur());
    }
    return valeur; // par convention, une affectation a pour valeur la valeur affectée
}

////////////////////////////////////////////////////////////////////////////////

void NoeudAffectation::afficher(unsigned short indentation) {

    Noeud::afficher(indentation);
    cout << "Noeud - Affectation" << endl;
    variable->afficher(indentation + 1); // on affiche variable et expression
    expression->afficher(indentation + 1); // en augmentant l'indentation
}

////////////////////////////////////////////////////////////////////////////////

void NoeudAffectation::afficherEnC(unsigned short indentation) {
    // affiche la traduction du languade en C

    indentation = indentation;
    this->variable->afficherEnC();
    cout << " = ";
    this->expression->afficherEnC();
}

////////////////////////////////////////////////////////////////////////////////
// NoeudOperateurBinaire
////////////////////////////////////////////////////////////////////////////////

NoeudOperateurBinaire::NoeudOperateurBinaire(Symbole operateur,
        Noeud* operandeGauche,
        Noeud* operandeDroit) {

    this->operateur = operateur;
    this->operandeGauche = operandeGauche;
    this->operandeDroit = operandeDroit;
}

////////////////////////////////////////////////////////////////////////////////

Valeur* NoeudOperateurBinaire::getValeur() {
    Valeur* valeur = NULL;
    Valeur* og = NULL;
    Valeur* od = NULL;
    bool str = false, ch = false, in = false, fl = false;
    if (typeid (*operandeGauche->getValeur()) == typeid (ValeurChaine) &&
            typeid (*operandeGauche->getValeur()) == typeid (ValeurChaine)) {
        str = true;
    } else if (typeid (*operandeGauche->getValeur()) == typeid (ValeurCaractere) &&
            typeid (*operandeGauche->getValeur()) == typeid (ValeurCaractere)) {
        ch = true;
    } else if (typeid (*operandeGauche->getValeur()) == typeid (ValeurEntiere) &&
            typeid (*operandeGauche->getValeur()) == typeid (ValeurEntiere)) {
        in = true;
    } else if (typeid (*operandeGauche->getValeur()) == typeid (ValeurReelle) &&
            typeid (*operandeGauche->getValeur()) == typeid (ValeurReelle)) {
        fl = true;
    } else {
        ComparaisonException ce;
        throw (ce);
    }
    if (in) {
        od = operandeDroit->getValeur();
        og = operandeGauche->getValeur();
        if (this->operateur == "+")
            valeur = new ValeurEntiere(((ValeurEntiere*) og)->getValeur() + ((ValeurEntiere*) od)->getValeur());
        else if (this->operateur == "-")
            valeur = new ValeurEntiere(((ValeurEntiere*) og)->getValeur() - ((ValeurEntiere*) od)->getValeur());
        else if (this->operateur == "*")
            valeur = new ValeurEntiere(((ValeurEntiere*) og)->getValeur() * ((ValeurEntiere*) od)->getValeur());
        else if (this->operateur == "==")
            valeur = new ValeurEntiere(((ValeurEntiere*) og)->getValeur() == ((ValeurEntiere*) od)->getValeur());
        else if (this->operateur == "!=")
            valeur = new ValeurEntiere(((ValeurEntiere*) og)->getValeur() != ((ValeurEntiere*) od)->getValeur());
        else if (this->operateur == "<")
            valeur = new ValeurEntiere(((ValeurEntiere*) og)->getValeur() < ((ValeurEntiere*) od)->getValeur());
        else if (this->operateur == "<=")
            valeur = new ValeurEntiere(((ValeurEntiere*) og)->getValeur() <= ((ValeurEntiere*) od)->getValeur());
        else if (this->operateur == ">")
            valeur = new ValeurEntiere(((ValeurEntiere*) og)->getValeur() > ((ValeurEntiere*) od)->getValeur());
        else if (this->operateur == ">=")
            valeur = new ValeurEntiere(((ValeurEntiere*) og)->getValeur() >= ((ValeurEntiere*) od)->getValeur());
        else if (this->operateur == "non")
            valeur = new ValeurEntiere(!((ValeurEntiere*) od)->getValeur());
        else if (this->operateur == "et")
            valeur = new ValeurEntiere(((ValeurEntiere*) og)->getValeur() && ((ValeurEntiere*) od)->getValeur());
        else if (this->operateur == "ou")
            valeur = new ValeurEntiere(((ValeurEntiere*) og)->getValeur() || ((ValeurEntiere*) od)->getValeur());
        else if (((ValeurEntiere*) od)->getValeur() != 0) // this->operateur=="/"
            valeur = new ValeurEntiere(((ValeurEntiere*) og)->getValeur() / ((ValeurEntiere*) od)->getValeur());
        else {
            cout << "Erreur pendant l'interpretation : division par zero" << endl;
            DivisionException de;
            throw (de);
        }
    } else if (fl) {
        od = operandeDroit->getValeur();
        og = operandeGauche->getValeur();
        if (this->operateur == "+")
            valeur = new ValeurReelle(((ValeurReelle*) og)->getValeur() + ((ValeurReelle*) od)->getValeur());
        else if (this->operateur == "-")
            valeur = new ValeurReelle(((ValeurReelle*) og)->getValeur() - ((ValeurReelle*) od)->getValeur());
        else if (this->operateur == "*")
            valeur = new ValeurReelle(((ValeurReelle*) og)->getValeur() * ((ValeurReelle*) od)->getValeur());
        else if (this->operateur == "==")
            valeur = new ValeurReelle(((ValeurReelle*) og)->getValeur() == ((ValeurReelle*) od)->getValeur());
        else if (this->operateur == "!=")
            valeur = new ValeurReelle(((ValeurReelle*) og)->getValeur() != ((ValeurReelle*) od)->getValeur());
        else if (this->operateur == "<")
            valeur = new ValeurReelle(((ValeurReelle*) og)->getValeur() < ((ValeurReelle*) od)->getValeur());
        else if (this->operateur == "<=")
            valeur = new ValeurReelle(((ValeurReelle*) og)->getValeur() <= ((ValeurReelle*) od)->getValeur());
        else if (this->operateur == ">")
            valeur = new ValeurReelle(((ValeurReelle*) og)->getValeur() > ((ValeurReelle*) od)->getValeur());
        else if (this->operateur == ">=")
            valeur = new ValeurReelle(((ValeurReelle*) og)->getValeur() >= ((ValeurReelle*) od)->getValeur());
        else if (this->operateur == "non")
            valeur = new ValeurReelle(!((ValeurReelle*) od)->getValeur());
        else if (this->operateur == "et")
            valeur = new ValeurReelle(((ValeurReelle*) og)->getValeur() && ((ValeurReelle*) od)->getValeur());
        else if (this->operateur == "ou")
            valeur = new ValeurReelle(((ValeurReelle*) og)->getValeur() || ((ValeurReelle*) od)->getValeur());
        else if (((ValeurReelle*) od)->getValeur() != 0) // this->operateur=="/"
            valeur = new ValeurReelle(((ValeurReelle*) og)->getValeur() / ((ValeurReelle*) od)->getValeur());
        else {
            cout << "Erreur pendant l'interpretation : division par zero" << endl;
            DivisionException de;
            throw (de);
        }
    } else if (str) {
        od = operandeDroit->getValeur();
        og = operandeGauche->getValeur();
        string str1 = ((ValeurChaine*) og)->getValeur();
        string str2 = ((ValeurChaine*) od)->getValeur();
        if (this->operateur == "!=")
            valeur = new ValeurEntiere(str1.compare(str2));
        else if (this->operateur == "==") {
            if (str1.compare(str2) == 0)
                valeur = new ValeurEntiere(1);
            else
                valeur = new ValeurEntiere(0);
        } else if (this->operateur == "+") {
            string estr1 = str1.erase(str1.length() - 1, 1);
            string estr2 = str2.erase(0, 1);
            valeur = new ValeurChaine(estr1 += estr2);
        } else {
            cout << "Erreur pendant l'interpretation : Cette comparaison est impossible entre ces deux chaines" << endl;
            ComparaisonException ce;
            throw (ce);
        }
    } else if (ch) {
        od = operandeDroit->getValeur();
        og = operandeGauche->getValeur();
        if (this->operateur == "==")
            valeur = new ValeurEntiere(((ValeurCaractere*) og)->getValeur() == ((ValeurCaractere*) od)->getValeur());
        else if (this->operateur == "!=")
            valeur = new ValeurEntiere(((ValeurCaractere*) og)->getValeur() != ((ValeurCaractere*) od)->getValeur());
        else {
            cout << "Erreur pendant l'interpretation : Cette comparaison est impossible entre ces deux caractere" << endl;
            ComparaisonException ce;
            throw (ce);
        }
    }
    return valeur;
}

////////////////////////////////////////////////////////////////////////////////

void NoeudOperateurBinaire::afficher(unsigned short indentation) {

    Noeud::afficher(indentation);
    cout << "Noeud - Operateur Binaire \"" << this->operateur.getChaine() << "\" applique a : " << endl;
    operandeGauche->afficher(indentation + 1); // on affiche fils gauche et fils droit
    operandeDroit->afficher(indentation + 1); // en augmentant l'indentation
}

////////////////////////////////////////////////////////////////////////////////

void NoeudOperateurBinaire::afficherEnC(unsigned short indentation) {
    // affiche la traduction du languade en C
    indentation = indentation;
    Valeur* od = operandeDroit->getValeur();
    cout << "(";
    if (this->operateur != "non")
        operandeGauche->afficherEnC();
    if (this->operateur == "+") cout << " + ";
    else if (this->operateur == "-") cout << " - ";
    else if (this->operateur == "*") cout << " * ";
    else if (this->operateur == "==") cout << " == ";
    else if (this->operateur == "!=") cout << " != ";
    else if (this->operateur == "<") cout << " < ";
    else if (this->operateur == "<=") cout << " <= ";
    else if (this->operateur == ">") cout << " > ";
    else if (this->operateur == ">=") cout << " >= ";
    else if (this->operateur == "non") cout << "!";
    else if (this->operateur == "et") cout << " && ";
    else if (this->operateur == "ou") cout << " || ";
    else

        if (od != 0) cout << "/";
    operandeDroit->afficherEnC();
    cout << ")";
}

////////////////////////////////////////////////////////////////////////////////
// NoeudInstSi
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////

NoeudInstSi::NoeudInstSi(Noeud* expBool, Noeud* seqInst, Noeud* sinon)
// construit une instruction si : expBool seqInst sinon
: expBool(expBool), seqInst(seqInst), sinon(sinon) {
}

////////////////////////////////////////////////////////////////////////////////

Valeur* NoeudInstSi::getValeur() {
    if (typeid (*expBool->getValeur()) == typeid (ValeurEntiere)) {
        if (((ValeurEntiere*) expBool->getValeur())->getValeur()) {
            seqInst->getValeur();
        } else if (sinon != NULL)
            sinon->getValeur();
    } else {
        ComparaisonException ce;
        throw (ce);
    }
    return NULL;
}
////////////////////////////////////////////////////////////////////////////////

void NoeudInstSi::afficher(unsigned short indentation) {
    // affiche l'opération
    Noeud::afficher(indentation);
    cout << "Noeud - Instruction Conditionelle" << endl;
    if (expBool != NULL)
        expBool->afficher(indentation + 1); // on affiche variable et expression
    seqInst->afficher(indentation + 1); // en augmentant l'indentation

    if (sinon != NULL)
        sinon->afficher(indentation + 1);
}

////////////////////////////////////////////////////////////////////////////////

void NoeudInstSi::afficherEnC(unsigned short indentation) {
    // affiche la traduction du languade en C

    cout << " if (";
    this->expBool->afficherEnC();
    cout << ") {" << endl;
    this->seqInst->afficherEnC(indentation + 1);
    cout << " }";
    if (this->sinon != NULL) {

        cout << " else {";
        this->sinon->afficherEnC(indentation);
        cout << " }";
    }
}

////////////////////////////////////////////////////////////////////////////////

void NoeudInstSi::setSinon(Noeud* sinon) {
    // l'attribut sinon prend pour valeur sinon

    this->sinon = sinon;
}

////////////////////////////////////////////////////////////////////////////////

Noeud* NoeudInstSi::getSinon() {
    // retourne le pointeur sinon

    return this->sinon;
}

////////////////////////////////////////////////////////////////////////////////

Noeud* NoeudInstSi::getExp() {
    //retourne l'expression booléenne du premier si

    return this->expBool;
}

////////////////////////////////////////////////////////////////////////////////

Noeud* NoeudInstSi::getSeq() {
    //retourne l'expression booléenne du premier si

    return this->seqInst;
}

////////////////////////////////////////////////////////////////////////////////
// NoeudBoucle
////////////////////////////////////////////////////////////////////////////////

NoeudBoucle::NoeudBoucle(Noeud* expBool, Noeud* seqInst)
// construit une instruction Boucle.
: expBool(expBool), seqInst(seqInst) {
}

////////////////////////////////////////////////////////////////////////////////
// NoeudInstTq
////////////////////////////////////////////////////////////////////////////////

NoeudInstTq::NoeudInstTq(Noeud* expBool, Noeud* seqInst)
// construit une instruction Boucle.
: NoeudBoucle(expBool, seqInst) {
}

////////////////////////////////////////////////////////////////////////////////

Valeur* NoeudInstTq::getValeur() {
    if (typeid (*expBool->getValeur()) == typeid (ValeurEntiere)) {
        while (((ValeurEntiere*) expBool->getValeur())->getValeur())
            seqInst->getValeur();
    } else {
        ComparaisonException ce;
        throw (ce);
    }
    return NULL;
}

////////////////////////////////////////////////////////////////////////////////

void NoeudInstTq::afficher(unsigned short indentation) {
    // affiche l'opération

    Noeud::afficher(indentation);
    cout << "Noeud - Instruction Tant que" << endl;
    expBool->afficher(indentation + 1); // on affiche variable et expression
    seqInst->afficher(indentation + 1); // en augmentant l'indentation
}

////////////////////////////////////////////////////////////////////////////////

void NoeudInstTq::afficherEnC(unsigned short indentation) {
    // affiche la traduction du languade en C

    cout << "while (";
    this->expBool->afficherEnC();
    cout << ") {" << endl;
    this->seqInst->afficherEnC(indentation + 1);
    cout << "}";
}

////////////////////////////////////////////////////////////////////////////////
// NoeudInstRepeter
////////////////////////////////////////////////////////////////////////////////

NoeudInstRepeter::NoeudInstRepeter(Noeud* expBool, Noeud* seqInst)
// construit une instruction Boucle.
: NoeudBoucle(expBool, seqInst) {
}

////////////////////////////////////////////////////////////////////////////////

Valeur* NoeudInstRepeter::getValeur() {
        do
            seqInst->getValeur(); 
        while (((ValeurEntiere*) expBool->getValeur())->getValeur());
    return NULL;
}

////////////////////////////////////////////////////////////////////////////////

void NoeudInstRepeter::afficher(unsigned short indentation) {
    // affiche l'opération

    Noeud::afficher(indentation);
    cout << "Noeud - Instruction Repeter" << endl;
    expBool->afficher(indentation + 1); // on affiche variable et expression
    seqInst->afficher(indentation + 1); // en augmentant l'indentation
}

////////////////////////////////////////////////////////////////////////////////

void NoeudInstRepeter::afficherEnC(unsigned short indentation) {
    // affiche la traduction du languade en C

    cout << "do {" << endl;
    this->seqInst->afficherEnC(indentation + 1);
    cout << "} while (";
    this->expBool->afficherEnC();
    cout << ")";
}

////////////////////////////////////////////////////////////////////////////////
// NoeudInstPour
////////////////////////////////////////////////////////////////////////////////

NoeudInstPour::NoeudInstPour(Noeud* expBool, Noeud* seqInst, Noeud* affectation1, Noeud * affectation2)
// construit une instruction Boucle.
: NoeudBoucle(expBool, seqInst), affectation1(affectation1), affectation2(affectation2) {
}

////////////////////////////////////////////////////////////////////////////////

Valeur * NoeudInstPour::getValeur() {
    for (affectation1->getValeur(); ((ValeurEntiere*) expBool->getValeur())->getValeur(); affectation2->getValeur()) {
        seqInst->getValeur();
    }
    return NULL;
}

////////////////////////////////////////////////////////////////////////////////

void NoeudInstPour::afficher(unsigned short indentation) {
    // affiche l'opération

    Noeud::afficher(indentation);
    cout << "Noeud - Instruction Pour" << endl;
    affectation1->afficher(indentation + 1);
    expBool->afficher(indentation + 1); // on affiche variable et expression
    affectation2->afficher(indentation + 1);
    seqInst->afficher(indentation + 1); // en augmentant l'indentation
}

////////////////////////////////////////////////////////////////////////////////

void NoeudInstPour::afficherEnC(unsigned short indentation) {
    // affiche la traduction du languade en C

    cout << "for (";
    this->affectation1->afficherEnC();
    cout << "; ";
    this->expBool->afficherEnC();
    cout << "; ";
    this->affectation2->afficherEnC();
    cout << ") {" << endl;
    this->seqInst->afficherEnC(indentation + 1);
    cout << "}";
}

////////////////////////////////////////////////////////////////////////////////
// NoeudInstLire
////////////////////////////////////////////////////////////////////////////////

NoeudInstLire::NoeudInstLire(Noeud * variable)
// construit une instruction Lire.
: variable(variable) {
}

////////////////////////////////////////////////////////////////////////////////

Valeur * NoeudInstLire::getValeur() {
    if (typeid (*variable->getValeur()) == typeid (ValeurChaine)) {
        string str, str2;
        getline(cin, str);
        str2 = "\"" + str ;
        str2.push_back('"');
        ((SymboleValue*) variable)->setValeur(new ValeurChaine(str2));
    } else if (typeid (*variable->getValeur()) == typeid (ValeurCaractere)) {
        char ch;
        cin >> ch;
        cin.ignore(256, '\n');
        ((SymboleValue*) variable)->setValeur(new ValeurCaractere(ch));
    } else if (typeid (*variable->getValeur()) == typeid (ValeurEntiere)) {
        int i;
        cin >> i;
        cin.ignore(256, '\n');
        ((SymboleValue*) variable)->setValeur(new ValeurEntiere(i));
    } else if (typeid (*variable->getValeur()) == typeid (ValeurReelle)) {
        float f;
        cin >> f;
        cin.ignore(256, '\n');
        ((SymboleValue*) variable)->setValeur(new ValeurReelle(f));
    } 
    return NULL; // par convention, une affectation a pour valeur la valeur affectée
}

////////////////////////////////////////////////////////////////////////////////

void NoeudInstLire::afficher(unsigned short indentation) {
    // affiche l'opération

    Noeud::afficher(indentation);
    cout << "Noeud - Instruction Lire" << endl;
    variable->afficher(indentation + 1); // on affiche variable et expression
}

////////////////////////////////////////////////////////////////////////////////

void NoeudInstLire::afficherEnC(unsigned short indentation) {
    // affiche la traduction du languade en 
    indentation = indentation;
    if (variable->getValeur() == 0)
        cout << "scanf(\"%c\", &";

    else
        cout << "scanf(\"%d\", &";
    this->variable->afficherEnC();
    cout << ")" << endl;
}

////////////////////////////////////////////////////////////////////////////////
// NoeudInstEcrire
////////////////////////////////////////////////////////////////////////////////

NoeudInstEcrire::NoeudInstEcrire(Noeud * exp)
// construit une instruction Ecrire.
: exp(exp) {
}

////////////////////////////////////////////////////////////////////////////////

Valeur * NoeudInstEcrire::getValeur() {
    if (typeid (*exp) == typeid (SymboleValue) &&
            *(SymboleValue*) exp == "<CHAINE>") {
        string s = ((ValeurChaine*) exp->getValeur())->getValeur();
        s.erase(0, 1);
        s.erase(s.length() - 1, 1);
        cout << s;
    } else if (typeid (*exp) == typeid (SymboleValue) &&
            *(SymboleValue*) exp == "<CARACTERE>") {
        cout << ((ValeurCaractere*) exp->getValeur())->getValeur();
    } else if (typeid (*exp) == typeid (SymboleValue) &&
            *(SymboleValue*) exp == "<ENTIER>") {
        cout << ((ValeurEntiere*) exp->getValeur())->getValeur();
    } else if (typeid (*exp) == typeid (SymboleValue) &&
            *(SymboleValue*) exp == "<REEL>") {
        cout << ((ValeurReelle*) exp->getValeur())->getValeur();
    } else if (typeid (*exp) == typeid (SymboleValue) &&
            *(SymboleValue*) exp == "<VARIABLE>") {
        if (typeid (*exp->getValeur()) == typeid (ValeurEntiere))
            cout << ((ValeurEntiere*) exp->getValeur())->getValeur();
        else if (typeid (*exp->getValeur()) == typeid (ValeurReelle))
            cout << ((ValeurReelle*) exp->getValeur())->getValeur();
        else if (typeid (*exp->getValeur()) == typeid (ValeurChaine)) {
            string s = ((ValeurChaine*) exp->getValeur())->getValeur();
            s.erase(0, 1);
            s.erase(s.length() - 1, 1);
            cout << s;
        } else if (typeid (*exp->getValeur()) == typeid (ValeurCaractere))
            cout << ((ValeurCaractere*) exp->getValeur())->getValeur();
    }
    return NULL;
}

////////////////////////////////////////////////////////////////////////////////

void NoeudInstEcrire::afficher(unsigned short indentation) {
    // affiche l'opération

    Noeud::afficher(indentation);
    cout << "Noeud - Instruction Ecrire" << endl;
    exp->afficher(indentation + 1);
}

////////////////////////////////////////////////////////////////////////////////

void NoeudInstEcrire::afficherEnC(unsigned short indentation) {
    // affiche la traduction du languade en C
    indentation = indentation;
    cout << "printf(";
    if (typeid (*exp) == typeid (SymboleValue) &&
            *(SymboleValue*) exp == "<CHAINE>")
        this->exp->afficherEnC();
    else {

        cout << "\"%d\", ";
        this->exp->afficherEnC();
    }
    cout << ")";
}

////////////////////////////////////////////////////////////////////////////////
// NoeudInstChoix
////////////////////////////////////////////////////////////////////////////////

NoeudInstSelon::NoeudInstSelon(NoeudInstSi * instsi)
// construit une instruction choix.
: instsi(instsi) {
}

Valeur * NoeudInstSelon::getValeur() {
    instsi->getValeur();

    return NULL;
}

void NoeudInstSelon::afficher(unsigned short indentation) {
    // affiche l'opération

    this->instsi->afficher(indentation);
}

////////////////////////////////////////////////////////////////////////////////

void NoeudInstSelon::afficherEnC(unsigned short indentation) {
    // affiche la traduction du languade en C
    this->instsi->afficherEnC(indentation);
}
